<?php
/*
 * 筛选靓号
 * 靓号规则：
 * 一，ABC 3连及以上
 * 二，AAA 3同及以上
 * 三，AABB 2对及以上
 * 四，ABAB
 * 五，ABAABA
 */

namespace App\Services\Tools;

class GoodNumberService
{
    public function genUserId()
    {
        return $this->getUserCode();

        $id = "";
        $arr = [1, 2, 3, 5, 6, 7, 8, 9];
        $rand_index = rand(0, 6);
        $id .= $arr[$rand_index];

        for ($i = 0; $i < 5; ++$i) {
            $id .= rand(0, 9);
        }

        if (!$this->reserveNumber($id)) {
            $flag = $this->isNiceNumber($id);
            if ($flag) {
                return $this->genUserId();
            }
        } else {
            return $this->genUserId();
        }

        return $id;
    }
    public function genUserNo()
    {
        return $this->getUserNo();
    }

    function reserveNumber($numStr)
    {
        if (intval($numStr) <= 10010) {
            return true;
        }

        return false;
    }

    function isNiceNumber($numStr)
    {
        //转化成整数
        $a0 = (int) $numStr[0];
        $a1 = (int) $numStr[1];
        $a2 = (int) $numStr[2];
        $a3 = (int) $numStr[3];
        $a4 = (int) $numStr[4];
        $a5 = (int) $numStr[5];

        //3同或以上
        if ($this->getSameNumCount($a0, $a1, $a2, $a3, $a4, $a5) >= 3) {
            return true;
        }
        //3顺子或以上
        if ($this->getSeriesNumCount($a0, $a1, $a2, $a3, $a4, $a5) >= 3) {
            return true;
        }
        //2对或以上
        if ($this->getPairsNumCount($a0, $a1, $a2, $a3, $a4, $a5) >= 2) {
            return true;
        }
        //ABAB类型
        if ($this->checkAb($a0, $a1, $a2, $a3, $a4, $a5)) {
            return true;
        }
        //ABAABA
        if ($this->isSameNumSeries($a1, $a4)) {
            if ($this->isSameNumSeries($a0, $a2, $a3, $a5)) {
                return true;
            }
        }

        return false;
    }

    //获取连续相同的数字个数
    function getSameNumCount()
    {
        $len = func_num_args();
        $count = $max = 0;
        for ($i = 1; $i < $len; $i++) {
            $next = func_get_arg($i);
            $before = func_get_arg($i - 1);
            if ($next == $before) {
                $count++;
                if ($max < $count) {
                    $max = $count;
                }
            } else {
                $count = 0;
            }
        }

        return $max > 0 ? ($max + 1) : 0;
    }

    //获取顺子的长度
    function getSeriesNumCount()
    {
        $len = func_num_args();
        $count = $max = 0;
        $asc = 1;
        for ($i = 1; $i < $len; $i++) {
            $next = func_get_arg($i);
            $before = func_get_arg($i - 1);
            $asc_temp = $next < $before ? -1 : 1;
            if ($asc_temp != $asc) {
                $count = 0;
                $asc = $asc_temp;
            }
            if ($next == ($before + $asc_temp)) {
                $count++;
                if ($max < $count) {
                    $max = $count;
                }
            } else {
                $count = 0;
            }
        }

        return $max > 0 ? ($max + 1) : 0;
    }

    //获取对子的个数
    function getPairsNumCount()
    {
        $len = func_num_args();
        $count = $max = 0;
        for ($i = 1; $i < $len; $i++) {
            $next = func_get_arg($i);
            $before = func_get_arg($i - 1);
            if ($next == $before) {
                $count++;
                $i++;
                if ($max < $count) {
                    $max = $count;
                }
            }
        }

        return $max > 0 ? $max : 0;
    }

    //判断是否ABAB类型
    function checkAb()
    {
        for ($i = 1; $i < 4; $i++) {
            $a = func_get_arg($i - 1);
            $b = func_get_arg($i);
            $c = func_get_arg($i + 1);
            $d = func_get_arg($i + 2);
            if ($c == $a && $d == $b) {
                return true;
            }
        }

        return false;
    }

    function isSameNumSeries()
    {
        $len = func_num_args();
        $flag = false;
        $count = 0;
        for ($i = 1; $i < $len; $i++) {
            if (func_get_arg($i) == func_get_arg(0)) {
                $count++;
            } else {
                return false;
            }
        }
        if ($count == $len - 1) {
            $flag = true;
        }

        return $flag;
    }

    function isLianNumSeries()
    {
        $len = func_num_args();
        $flag = false;
        $count = 0;
        $asc = 1;

        if (!(func_get_arg(0) == func_get_arg($len - 1) + ($len - 1) || func_get_arg(0) == func_get_arg($len - 1) - ($len - 1))) {
            return false;
        }

        if (func_get_arg(0) > func_get_arg($len - 1)) {
            $asc = -1;
        }

        for ($i = 1; $i < $len; $i++) {
            if (func_get_arg($i - 1) + $asc == func_get_arg($i)) { //升序
                $count++;
            }
        }

        if ($count == $len - 1) {
            $flag = true;
        }

        return $flag;
    }

    public function getGoodNumber()
    {
        set_time_limit(0);
        ob_end_clean();
        ob_implicit_flush();
        header('X-Accel-Buffering: no'); // 关键是加了这一行。

        $arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
        $n = $t = 0;
        foreach ($arr as $a) {
            for ($b = 0; $b < 10; $b++) {
                for ($c = 0; $c < 10; $c++) {
                    for ($d = 0; $d < 10; $d++) {
                        for ($e = 0; $e < 10; $e++) {
                            for ($f = 0; $f < 10; $f++) {
                                $number = $a.$b.$c.$d.$e.$f;
                                if ($this->isNiceNumber($number)) {
                                    $n++;
                                    //echo $number . "<br>";
                                }
                                $t++;
                            }
                        }
                    }
                }
            }
        }
        echo $t.'|'.$n;
    }

    public function getMultipleUserId()
    {
        $ids = [];
        while (count($ids) < 1000) {
            $id = mt_rand(100100, 999999);
            if (!$this->isGoodNumber($id)) {
                $ids[$id] = 1;
            }
        }

        return $ids;
    }

    public function getUserNo()
    {
        $redis_key = 'user:no:set';
        if (app('redis')->scard($redis_key) <= 0) {
            return $this->createUserNo();
        } else {
            $id = app('redis')->spop($redis_key);
            if (!$id) {
                return $this->createUserNo();
            }

            return $id;
        }
    }
    public function getUserCode()
    {
        $redis_key = 'user:code:set';
        if (app('redis')->scard($redis_key) <= 0) {
            return $this->createUserCode();
        } else {
            $id = app('redis')->spop($redis_key);
            if (!$id) {
                return $this->createUserCode();
            }

            return $id;
        }
    }

    public function createUserCode()
    {
        $redis_key = 'user:code:set';
        $ids = $this->getMultipleUserId();
        $user_list = app('model_user_data')->select('user_code')->whereIn('user_code', array_keys($ids))->get()->toArray();
        foreach ($user_list as $user_code) {
            unset($ids[$user_code['user_code']]);
        }
        $all_ids = array_keys($ids);
        $id = $all_ids[0] ?? 0;
        unset($all_ids[0]);
        app('redis')->sadd($redis_key, ...$all_ids);

        return $id;
    }
    //生成用户邀请码
    public function createUserNo()
    {
        $redis_key = 'user:no:set';
        $ids = $this->getMultipleUserId();
        $user_list = app('model_user')->whereIn('user_no', array_keys($ids))->value('user_no');
        foreach ($user_list as $user_code) {
            unset($ids[$user_code]);
        }
        $all_ids = array_keys($ids);
        $id = $all_ids[0] ?? 0;
        unset($all_ids[0]);
        app('redis')->sadd($redis_key, ...$all_ids);

        return $id;
    }

    public function isGoodNumber($number)
    {
        //AAA BBB
        $preg = '/(\d)\1{2,}/';
        if (preg_match($preg, $number)) {
            return true;
        }

        //如ABAB
        $preg = '/(\d\d)\1{2,}/';
        if (preg_match($preg, $number)) {
            return true;
        }

        //如ABCABC
        $preg_fuhao2 = '/(\d\d\d)\1{1,}/';
        if (preg_match($preg_fuhao2, $number)) {
            return true;
        }

        //如 XXAA XXXAA
        $preg = '/([\d])\1{1,}([\d])\2{1,}/';
        if (preg_match($preg, $number)) {
            return true;
        }

        //3. 保留串号：如 ABCDFG(正序)
        //5. 部分串号：如 XXABCD （主要判断后四位的情况）
        $preg = '/(?:0(?=1)|1(?=2)|2(?=3)|3(?=4)|4(?=5)|5(?=6)|6(?=7)|7(?=8)|8(?=9)){2,}/';
        if (preg_match($preg, $number)) {
            return true;
        }
        //3. 保留串号：如 ABCDFG(倒序)
        $preg = '/(?:9(?=8)|8(?=7)|7(?=6)|6(?=5)|5(?=4)|4(?=3)|3(?=2)|2(?=1)|1(?=0)){2,}/';
        if (preg_match($preg, $number)) {
            return true;
        }

        return false;
    }

    // 是否为管理员后台设置的靓号
    public function verifyByAdmin( $good_number ) {
        $count = app('model_good_number')->where('good_number', $good_number)->count();
        // echo $this->db->getlastsql();exit;
        if( $count){
            // $this->apiReturn(V(1, '该号码为靓号'));
            return true;
        }else{
            // $this->apiReturn(V(1, '改号码为普通号'));
            return false;
        }
    }
}

